; Build:
; # ml /c syscall_win32.asm
; # link /subsystem:console syscall_win32.obj 
.386
.model flat,stdcall
.data

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;            SDK prototypes            ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NULL            EQU 0

UNICODE_STRING STRUCT
    Len             WORD ?
    MaximumLength   WORD ?
    Buffer          DWORD ?
UNICODE_STRING ENDS

OBJECT_ATTRIBUTES STRUCT
    Len                         DWORD ?
    RootDirectory               DWORD ?
    ObjectName                  DWORD ?
    Attributes                  DWORD ?
    SecurityDescriptor          DWORD ?
    SecurityQualityOfService    DWORD ?
OBJECT_ATTRIBUTES ENDS

IO_STATUS_BLOCK STRUCT
    Status  DWORD ?
    Pointer DWORD ?
IO_STATUS_BLOCK ENDS

ExitProcess PROTO :DWORD

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;         Program declarations         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; IMPORTANT: The paddding is required!!
STR_HELLO           DB      "Hello World!",0,0,0,0
STR_FILE            WORD    "\","?","?","\","C",":","\","t","e","s","t",".","t","x","t",0

.code

NtCreateFile PROC
    ; 25h(XP) or 42h(Win7)
    mov eax, 25h
    mov edx, 7ffe0300h
    call DWORD PTR [edx]
    retn 2ch
NtCreateFile ENDP

NtWriteFile PROC
    ; 112h(XP) or 18ch(Win7)
    mov eax, 112h
    mov edx, 7ffe0300h
    call DWORD PTR [edx]
    retn 24h
NtWriteFile ENDP

NtClose PROC
    ; 19h(XP) or 32h(Win7)
    mov eax, 19h
    mov edx, 7ffe0300h
    call DWORD PTR [edx]
    retn 4h
NtClose ENDP

main PROC
    ;LOCAL ntStatus:DWORD
    LOCAL us:UNICODE_STRING
    LOCAL oa:OBJECT_ATTRIBUTES
    LOCAL ioStatusBlock:IO_STATUS_BLOCK
    LOCAL hFile:DWORD
    ; 1. initialization
    mov us.Buffer, OFFSET STR_FILE
    mov us.Len, 30
    mov us.MaximumLength, 32
    mov oa.Len, TYPE OBJECT_ATTRIBUTES
    mov oa.RootDirectory, NULL
    lea eax, [us]
    mov oa.ObjectName, eax
    ; OBJ_KERNEL_HANDLE
    mov oa.Attributes, 200h
    mov oa.SecurityDescriptor, NULL
    mov oa.SecurityQualityOfService, NULL
    ; 2. parameters of NtCreateFile
    push 0
    push NULL
    ; FILE_SYNCHRONOUS_IO_NONALERT
    push 20h
    ; FILE_OVERWRITE_IF
    push 5h
    push 0
    ; FILE_ATTRIBUTE_NORMAL
    push 80h      
    push NULL
    lea eax, [ioStatusBlock]
    push eax
    lea eax, [oa]
    push eax
    ; GENERIC_ALL | SYNCHRONIZE
    push 10100000h
    lea eax, [hFile]
    push eax
    ; 3. call NtCreateFile
    call NtCreateFile
    ; 4. parameters of NtWriteFile
    push NULL
    push NULL
    push 12
    push OFFSET STR_HELLO
    lea eax, [ioStatusBlock]
    push eax
    push NULL
    push NULL
    push NULL
    push hFile
    ; 5. call NtWriteFile
    call NtWriteFile
    ; 6. parameters of NtClose
    push hFile
    ; 7. call NtClose
    call NtClose
    ; 8. Exit
    ;INVOKE ExitProcess, 0
    ret
main ENDP

END main

